package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.PaperQuestion;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.mapper.PaperMapper;
import com.atguigu.exam.mapper.PaperQuestionMapper;
import com.atguigu.exam.service.PaperQuestionService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.service.QuestionService;
import com.atguigu.exam.vo.PaperVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 试卷服务实现类
 */
@Slf4j
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {


    @Autowired
    private PaperQuestionService paperQuestionService;
    @Autowired
    private PaperQuestionMapper paperQuestionMapper;
    @Autowired
    private ExamRecordMapper examRecordMapper;

    @Override
    public Paper getPaperById(Integer id) {
        //这个查询中不包含题目的选项和答案
        return baseMapper.getPaperById(id);
    }

    @Transactional
    @Override
    public void createPaper(PaperVo paperVo) {
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()));
        if (exists) {
            throw new ExamException(611, "试卷名字已经存在，请重新创建！");
        }
        Paper paper = new Paper();
        // 属性复制
        BeanUtils.copyProperties(paperVo, paper);
        // 设置状态
        paper.setStatus("DRAFT");
        // 计算总分
        Map<Integer, BigDecimal> questions = paperVo.getQuestions();
        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(totalScore);
        paper.setQuestionCount(questions.size());
        baseMapper.insert(paper);
        List<PaperQuestion> paperQuestions = questions.entrySet().stream().map(entry -> {
            PaperQuestion paperQuestion = new PaperQuestion(paper.getId(), Long.valueOf(entry.getKey()), entry.getValue());
            return paperQuestion;
        }).collect(Collectors.toList());
        paperQuestionService.saveBatch(paperQuestions);
    }

    @Override
    public void updatePaper(Integer id, PaperVo paperVo) {

        //1.校验 （不能发布状态 ， 不能不同id,name相同）
        Paper paper = baseMapper.selectById(id);
        if ("PUBLISHED".equals(paper.getStatus())) {
            throw new ExamException(601, "发布状态下的试卷不允许修改！");
        }
        //校验id name
        LambdaQueryWrapper<Paper> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(Paper::getId, id);
        queryWrapper.eq(Paper::getName, paperVo.getName());
        long count = count(queryWrapper);
        if (count > 0) {
            throw new ExamException(602, "%s 试卷名字已经存在，请重新修改！".formatted(paperVo.getName()));
        }
        //2.试卷的主体
        BeanUtils.copyProperties(paperVo, paper);
        Map<Integer, BigDecimal> questions = paperVo.getQuestions();
        BigDecimal totalScore = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(totalScore);
        paper.setQuestionCount(questions.size());
        baseMapper.updateById(paper);
        //删除旧数据
        paperQuestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
        //添加新数据
        List<PaperQuestion> paperQuestions = questions.entrySet().stream().map(entry -> {
            PaperQuestion paperQuestion = new PaperQuestion(paper.getId(), Long.valueOf(entry.getKey()), entry.getValue());
            return paperQuestion;
        }).collect(Collectors.toList());
        paperQuestionService.saveBatch(paperQuestions);
    }

    @Override
    public void deletePaper(Integer id) {
        //1.不是发布状态
        Paper paper = baseMapper.selectById(id);
        if ("PUBLISHED".equals(paper.getStatus())) {
            throw new ExamException(603, "发布状态下的试卷不允许删除！");
        }
        //2.不能有关联的考试记录
        LambdaQueryWrapper<ExamRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ExamRecord::getExamId, id);
        Long count = examRecordMapper.selectCount(lambdaQueryWrapper);
        if (count > 0) {
            throw new ExamException(604, "当前试卷：%s 下面有关联 %s条考试记录！无法直接删除！".formatted(id, count));
        }
        //3.删除自身表
        baseMapper.deleteById(id);
        //4.删除中间表
        paperQuestionService.remove(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
    }

    @Override
    public void updatePaperStatus(Integer id, String status) {
        LambdaQueryWrapper<ExamRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ExamRecord::getExamId, id).eq(ExamRecord::getStatus, "进行中");
        Long count = examRecordMapper.selectCount(lambdaQueryWrapper);
        if (count > 0) {
            throw new ExamException(605, "该试卷正在考试，不能修改");
        }
        baseMapper.update(null, new LambdaUpdateWrapper<Paper>().set(Paper::getStatus, status).eq(Paper::getId, id));
    }
}